package cn.bandeqing.workTime.rpc.impl;

import cn.bandeqing.base.domain.CurrentWorkerUser;
import cn.bandeqing.base.resp.Resp;
import cn.bandeqing.config.service.IConfigService;
import cn.bandeqing.frame.exception.CodeException;
import cn.bandeqing.stp.StpWorkerUtil;
import cn.bandeqing.workTime.entity.WorkTime;
import cn.bandeqing.workTime.req.WorkTimeModifyReq;
import cn.bandeqing.workTime.resp.WorkTimeList;
import cn.bandeqing.workTime.rpc.IWorkTimeRpc;
import cn.bandeqing.workTime.service.IWorkTimeService;
import com.mybatisflex.core.query.QueryWrapper;
import io.github.linpeilie.Converter;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboService;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.date.DateField;
import org.dromara.hutool.core.date.DatePattern;
import org.dromara.hutool.core.date.DateTime;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.util.ObjUtil;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.text.DateFormat;
import java.util.Comparator;
import java.util.List;

import static cn.bandeqing.workTime.entity.table.WorkTimeTableDef.WORK_TIME;

@DubboService
public class WorkTimeRpcImpl implements IWorkTimeRpc {

    @Resource
    private IWorkTimeService workTimeService;
    @Resource
    private IConfigService configService;
    @Resource
    private Converter converter;

    @Override
    @Transactional
    public Resp<List<WorkTimeList>> list() {
        Integer workTimeDay = configService.keyInt("work_time_day", 7);
        DateTime nowDate = new DateTime();

        CurrentWorkerUser current = StpWorkerUtil.getCurrent();

        List<WorkTimeList> workTimeLists = workTimeService.listAs(QueryWrapper.create()
                .where(WORK_TIME.WORKER_ID.eq(current.getWorkerId()))
                .where(WORK_TIME.WT_DATE.ge(nowDate.toString(DatePattern.NORM_DATE_PATTERN)))
                .limit(workTimeDay), WorkTimeList.class);

        List<WorkTime> workTimesAdd = ListUtil.of();
        if (workTimeLists.isEmpty()) {
            for (int i = 0; i < workTimeDay; i++) {
                workTimesAdd.add(WorkTime.builder()
                        .workerId(current.getWorkerId())
                        .workerName(current.getWorkerNickName())
                        .wtDate(new Date(nowDate.getTime()))
                        .build());
                nowDate.offset(DateField.DAY_OF_YEAR, 1);
            }
        } else if (workTimeLists.size() < workTimeDay) {
            for (int i = 0; i < workTimeDay; i++) {
                boolean find = false;
                for (WorkTimeList wt : workTimeLists) {
                    if (DateUtil.isSameDay(nowDate, wt.getWtDate())) {
                        find = true;
                    }
                }
                if (!find) {
                    workTimesAdd.add(WorkTime.builder()
                            .workerId(current.getWorkerId())
                            .workerName(current.getWorkerNickName())
                            .wtDate(new Date(nowDate.getTime()))
                            .build());
                }
                nowDate.offset(DateField.DAY_OF_YEAR, 1);
            }
        }

        if (CollUtil.isNotEmpty(workTimesAdd)) {
            workTimeService.saveBatch(workTimesAdd);
            workTimeLists.addAll(converter.convert(workTimesAdd, WorkTimeList.class));
        }

        List<WorkTimeList> sortWorkTimeList = workTimeLists.stream().sorted(Comparator.comparing(WorkTimeList::getWtDate)).toList();

        return Resp.success(sortWorkTimeList);
    }

    @Override
    public Resp<Void> modify(WorkTimeModifyReq req) {
        WorkTime wt = converter.convert(req, WorkTime.class);
        boolean b = workTimeService.updateById(wt);
        Assert.isTrue(b, () -> new CodeException(""));
        return Resp.success();
    }

}
